<template>
  <div class="upload-card">
    <el-upload
      ref="uploadRef"
      v-bind="defaultAttr"
      v-if="props.mode !== 'detail' && filesList.length < (props.config?.limit || 5)"
      :file-list="filesList"
      action="#"
      :on-change="handleChange"
      :http-request="uploadFile"
      :show-file-list="false"
      :before-upload="handleBeforeUpload"
      :on-success="handleSuccess"
    >
      <div class="upload-btn">
        <el-icon><Plus /></el-icon>
      </div>
    </el-upload>
    <div class="upload-item" v-for="(item, index) in filesList" :key="item.uid || index">
      <el-tooltip class="box-item" effect="dark" :content="item?.name">
        <img :src="parsingImage(item)" alt="" @click.stop="showFile(item)" />
      </el-tooltip>

      <el-icon v-show="props.mode !== 'detail'" @click.stop="handleRemove(index)"><CircleCloseFilled /></el-icon>
    </div>
  </div>
  <Teleport to="#app">
    <div class="file-mark" v-if="markShow">
      <el-icon class="close-btn" @click="markShow = false"><CircleClose /></el-icon>
      <vab-only-office id="office-preview" :documentServerUrl="documentServerUrl" :config="fileConfig" />
    </div>
  </Teleport>
</template>

<script setup>
import { computed, watch } from 'vue'
import useUpload from '@/hooks/useUpload'
import { ElMessage } from 'element-plus'
import vabOnlyOffice from '@/components/docPreview/Index.vue'
import { CircleClose } from '@element-plus/icons-vue'
const { uploadFile, deleteFile } = useUpload()
const props = defineProps({
  modelValue: {
    type: Array,
  },
  config: {
    type: Object,
    default: () => {},
  },
  mode: {
    // 'edit' | 'detail' | 'add'
    type: String,
    default: 'detail',
  },
})
const fileTypeList = {
  docx: 'word',
  doc: 'word',
  pdf: 'pdf',
  xls: 'excel',
  xlsx: 'excel',
  ppt: 'ppt',
  pptx: 'ppt',
  zip: 'zip',
  rar: 'zip',
  '7z': 'zip',
  tar: 'zip',
  mp4: 'video',
  avi: 'video',
  rmvb: 'video',
  mov: 'video',
  flv: 'video',
  wmv: 'video',
  mkv: 'video',
  mp3: 'audio',
  wav: 'audio',
  png: 'image',
  jpg: 'image',
  jpeg: 'image',
  gif: 'image',
  bmp: 'image',
  webp: 'image',
}

// v-model
const emits = defineEmits(['update:modelValue', 'change'])
const uploadRef = ref()
const defaultAttr = computed(() => {
  // 设置默认绑定值
  let { attrs = {} } = props.config
  // 判断禁用
  attrs['disabled'] = props.config?.disabled || false
  // 数量
  attrs['limit'] = props.config?.limit || 3
  // 文件类型
  attrs['accept'] = props.config?.accept || '*'
  return { ...attrs }
})

// 文件
const filesList = ref(props?.modelValue || [])
watch(
  () => props?.modelValue,
  (newVal) => {
    filesList.value = newVal || []
  },
  { immediate: true, deep: true }
)

const handleChange = (file, files) => {
  filesList.value = files
  // 强制更新
  filesList.value = filesList.value.slice()
  emits('update:modelValue', files)
}
const handleRemove = (index) => {
  // deleteFile({ file: fileName })
  filesList.value.splice(index, 1)
}
const parsingImage = (file) => {
  // 如果存在 url，说明是已上传的文件
  if (file.url) {
    const ext = file.url.split('.').pop().toLowerCase()
    try {
      // 根据后缀返回对应图标
      return new URL(`/src/assets/images/base/${fileTypeList?.[ext] || 'file'}.png`, import.meta.url).href
    } catch {
      // 找不到对应图标时返回默认图标
      return new URL(`/src/assets/images/base/file.png`, import.meta.url).href
    }
  }

  // 处理其他类型文件
  const mimeTypes = {
    'application/pdf': 'pdf',
    'application/msword': 'word',
    'application/vnd.openxmlformats-officedocument.wordprocessingml.document': 'word',
    'application/vnd.ms-excel': 'excel',
    'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet': 'excel',
    'application/vnd.ms-powerpoint': 'ppt',
    'application/vnd.openxmlformats-officedocument.presentationml.presentation': 'ppt',
    'application/zip': 'zip',
    'application/x-rar-compressed': 'zip',
  }
  // 处理新上传的文件
  if (file.raw) {
    if (file.raw.type.startsWith('image/')) {
      return new URL(`/src/assets/images/base/image.png`, import.meta.url).href
    }
    // 获取文件类型后缀
    const fileType = file.raw.name.split('.').pop().toLowerCase()
    try {
      return new URL(`/src/assets/images/base/${mimeTypes?.[fileType] || 'file'}.png`, import.meta.url).href
    } catch {
      return new URL(`/src/assets/images/base/file.png`, import.meta.url).href
    }
  }

  return new URL(`/src/assets/images/base/file.png`, import.meta.url).href
}
// 处理文件下载
const downloadFile = (file) => {
  if (file.url) {
    // 如果是已上传的文件，直接下载
    const link = document.createElement('a')
    link.href = file.url
    link.download = file.name
    document.body.appendChild(link)
    link.click()
    document.body.removeChild(link)
  } else if (file.raw) {
    // 如果是新上传的文件，直接下载
    const link = document.createElement('a')
    link.href = URL.createObjectURL(file.raw)
    link.download = file.raw.name
    document.body.appendChild(link)
    link.click()
    document.body.removeChild(link)
  } else {
    ElMessage.error('文件不存在')
  }
}

const handleBeforeUpload = (files) => {
  // console.log('handleBeforeUpload', files)
}
const handleSuccess = (res) => {
  filesList.value[filesList.value.length - 1] = res
}

const markShow = ref(false)
const documentServerUrl = process.env.envConfig.OFFICE_URL
// 配置对象
const fileConfig = reactive({
  document: {
    fileType: 'docx',
    key: '',
    title: '',
    url: '',
    download: false,
  },
  documentType: 'word',
  height: '100%',
  width: '100%',
})
// 工具方法
const generateKey = (length) => {
  let result = ''
  const characters = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789'
  const charactersLength = characters.length
  for (let i = 0; i < length; i++) {
    result += characters.charAt(Math.floor(Math.random() * charactersLength))
  }
  return result
}
const showFile = (file) => {
  if (file?.url) {
    const ext = file.url.split('.').pop().toLowerCase()
    const fileUrl = file.url
    const fileName = file.name ? file.name : file.url.split('/').pop()
    if (['word', 'excel', 'pdf', 'ppt'].includes(fileTypeList?.[ext])) {
      const key = generateKey(14)
      const fileTypeListEmun = {
        word: 'word',
        excel: 'cell',
        pdf: 'pdf',
        ppt: 'slide',
      }
      fileConfig.documentType = fileTypeListEmun[fileTypeList?.[ext]]
      fileConfig.document.url = fileUrl
      fileConfig.document.title = fileName
      fileConfig.document.key = key
      fileConfig.document.fileType = ext
      markShow.value = true
    } else {
      ElMessage.error('当前文件类型不支持预览')
    }
  } else {
    ElMessage.error('当前文件不存在')
  }
}
</script>

<style lang="scss" scoped>
.upload-card {
  display: flex;
  gap: 8px;
  flex-wrap: wrap;
}
.upload-btn {
  width: 30px;
  height: 30px;
  border-radius: 6px;
  cursor: pointer;
  border: 1px dashed var(--el-border-color-darker);
  text-align: center;
}
.upload-item {
  width: 25px;
  height: 30px;
  position: relative;
  img {
    width: 100%;
    height: 100%;
    border-radius: 6px;
  }
  .el-icon {
    position: absolute;
    font-size: 16px;
    right: -6px;
    top: -6px;
    color: var(--el-color-danger);
    display: none;
    cursor: pointer;
  }
  &:hover {
    .el-icon {
      display: block;
    }
  }
}
</style>

<style>
.file-mark {
  position: fixed;
  top: 0;
  left: 0;
  width: 100vw;
  height: 100vh;
  background-color: rgba(0, 0, 0, 0.5);
  z-index: 9999;
  padding: 40px;
}
.file-mark .close-btn {
  font-size: 30px;
  color: #fff;
  position: absolute;
  right: 10px;
  top: 10px;
  cursor: pointer;
}
</style>
